
//-----------------------------------------------
#include "iomanger.h"
#include "log.h"
#include <atomic>
#include <random>

namespace tt01{

learnco::Logger::ptr g_logger = learnco::LoggerMgr::GetInstance()->getLogger("user");
std::atomic<size_t> count = {0};

void fun1(){

    LEARNCO_LOG_DEBUG(g_logger) << "No.1count " << ++count;
    learnco::Fiber::YieldToHold();
    LEARNCO_LOG_DEBUG(g_logger) << "No.2count " << ++count;
}

//往sheduler放入任务，会唤醒线程立即执行任务
void test_schenduler(){
    learnco::IOmanger iom(1, "pool", true);
    learnco::Scheduler *sched = learnco::Scheduler::GetThis();
    
    sleep(1);

    for(int i=0; i<10000; i++){
        sched->scheduler(&fun1);
    }
}

}//namespace 
//-----------------------------------------------



//-----------------------------------------------
//测试addEvent, delEvent delEventAll
#include "iomanger.h"
#include "log.h"

#include <assert.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <fcntl.h>

namespace tt02{

learnco::Logger::ptr g_logger = learnco::LoggerMgr::GetInstance()->getLogger("user");

void test_event(){

learnco::IOmanger iom(1, "pool", true);
    sleep(1);

int pipefd[2];
    assert(!pipe(pipefd));
    fcntl(pipefd[0],F_SETFL,O_NONBLOCK);


    iom.addEvent(pipefd[0], learnco::IOmanger::READ, [=](){
        LEARNCO_LOG_DEBUG(g_logger) << "fd=" << pipefd[0] << " read event has been trig1";
    });

    iom.addEvent(pipefd[0], learnco::IOmanger::WRITE, [=](){
        LEARNCO_LOG_DEBUG(g_logger) << "fd=" << pipefd[0] << " write event has been trig1";
    });

    sleep(1);
    LEARNCO_LOG_DEBUG(g_logger) << "fd=" << pipefd[0] << "  即将手动触发触发读事件";
    iom.delEventAll(pipefd[0],true);
    iom.delEvent(pipefd[0], learnco::IOmanger::READ, true);
    sleep(1);

    LEARNCO_LOG_DEBUG(g_logger) << "剩余存活fiber 个数: " << (uint64_t)learnco::Fiber::TotalFibers();
    LEARNCO_LOG_DEBUG(g_logger) << "剩余事件event 个数: " << (size_t)iom.getEventnum();
}

}//namespace 
//-----------------------------------------------



//-----------------------------------------------
//测试事件触发
#include "iomanger.h"
#include "log.h"

#include <assert.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <fcntl.h>

namespace tt03{

learnco::Logger::ptr g_logger = learnco::LoggerMgr::GetInstance()->getLogger("user");

void test_ioevent(){

    learnco::IOmanger iom(1, "pool", true);

    int pipefd[2];
    assert(!pipe(pipefd));
    fcntl(pipefd[0],F_SETFL,O_NONBLOCK);


    iom.addEvent(pipefd[0], learnco::IOmanger::READ, [=](){
        uint8_t dummy[256];
        while(read(pipefd[0], dummy, sizeof(dummy)) > 0);
        LEARNCO_LOG_DEBUG(g_logger) << "read event has been trig: " << dummy;

    });

    sleep(3);
    LEARNCO_LOG_DEBUG(g_logger) << "fd=" << pipefd[0] << "  即将触发读事件";
    write(pipefd[1],"T",1);
    sleep(1);

    LEARNCO_LOG_DEBUG(g_logger) << "剩余存活fiber 个数: " << (uint64_t)learnco::Fiber::TotalFibers();
    LEARNCO_LOG_DEBUG(g_logger) << "剩余事件event 个数: " << (size_t)iom.getEventnum();
}

}//namespace 
//-----------------------------------------------



//-----------------------------------------------
//测试EPOLLET EPOLLLT
//EPOLLET 边缘触发
//EPOLLLT 水平触发，未读完的话一直唤醒epoll_wait
#include "iomanger.h"
#include "log.h"
#include "thread.h"

#include <assert.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <fcntl.h>

namespace tt04{

learnco::Logger::ptr g_logger = learnco::LoggerMgr::GetInstance()->getLogger("user");


void test_et_lt(){

int m_epollfd = epoll_create1(0);

int pipefd[2];
    assert(!pipe(pipefd));  
    // fcntl(pipefd[0],F_SETFL,O_NONBLOCK);

epoll_event ev;
    ev.data.fd = pipefd[0];
    //ev.events =  EPOLLET | EPOLLIN;
    ev.events =   EPOLLIN;
    assert(!epoll_ctl(m_epollfd, EPOLL_CTL_ADD, pipefd[0], &ev));

learnco::Thread t1( [=](){
        const int MAX_EVENTS = 256;
        epoll_event* events = new epoll_event[MAX_EVENTS];
        
        while(true)
        {
            int nr;
            do {
                nr = epoll_wait(m_epollfd, events, MAX_EVENTS, -1);
            } while (nr < 0 && errno == EINTR);
            
            LEARNCO_LOG_DEBUG(g_logger) << "epoll wait " << nr;
            for(int i=0; i<nr; ++i){
                epoll_event& event = events[i];
                if(event.data.fd == pipefd[0]){
                    uint8_t dummy[2];
                    read(pipefd[0], dummy, 1);
                    LEARNCO_LOG_DEBUG(g_logger) << "read " << dummy;      
                }
            }
        }
    });

    sleep(1);
    write(pipefd[1],"TTTT",4);
    sleep(1);
    write(pipefd[1],"HHHH",4);
    t1.join();
}

}//namespace 
//-----------------------------------------------



//-----------------------------------------------
//测试timer任务
#include "iomanger.h"
#include "log.h"

#include <iostream>

namespace tt05{

learnco::Logger::ptr g_logger = learnco::LoggerMgr::GetInstance()->getLogger("user");
uint64_t count = 0;

void test_timer(){
    learnco::IOmanger iom;

    iom.addTimer(1000, [&](){
            LEARNCO_LOG_DEBUG(g_logger) << " 正在执行定时任务 timer count " << ++count; 
    }, true);

    iom.stop();
}

}//namespace 
//-----------------------------------------------

#include <string.h> 
int main()
{
    //tt01::test_schenduler();
    //tt02::test_event();
    tt03::test_ioevent();
    //tt04::test_et_lt();
    //tt05::test_timer();

    
    return 0;
}